package model

import (
	"common/helper"
	"database/sql"
	"errors"
	g "github.com/doug-martin/goqu/v9"
	"github.com/doug-martin/goqu/v9/exp"
	"net/url"
)

// 帐变数据
type TransactionData struct {
	T   int64               `json:"total"`
	D   []MemberTransaction `json:"d"`
	Agg string              `db:"agg" json:"agg"`
}

func RecordTransaction(page, pageSize int, startTime, endTime string, ex g.Ex) (TransactionData, error) {

	data := TransactionData{}

	if startTime != "" && endTime != "" {
		startAt, err := helper.TimeToLocMs(startTime, loc) // 毫秒级时间戳
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}

		endAt, err := helper.TimeToLocMs(endTime, loc) // 毫秒级时间戳
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}

		if startAt >= endAt {
			return data, errors.New(helper.QueryTimeRangeErr)
		}

		ex["created_at"] = g.Op{"between": exp.NewRangeVal(startAt, endAt)}
	}

	t := dialect.From("tbl_balance_transaction")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT(1)).Where(ex).ToSQL()
		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil {
			return data, pushLog(err, "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}

		query, _, _ = t.Select(g.L("sum(after_amount - before_amount)").As("agg")).Where(ex).ToSQL()
		err = meta.MerchantDB.Get(&data.Agg, query)
		if err != nil {
			return data, pushLog(err, "数据库错误")
		}
	}

	offset := pageSize * (page - 1)
	query, _, _ := t.Select(colsTransaction...).Where(ex).
		Offset(uint(offset)).Limit(uint(pageSize)).Order(g.C("created_at").Desc()).ToSQL()
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(err, "数据库错误")
	}
	return data, nil
}

func MerchantRecordTransaction(page, pageSize int, startTime, endTime, operatorId, username string, ex g.Ex) (TransactionData, error) {

	data := TransactionData{}

	if startTime != "" && endTime != "" {
		startAt, err := helper.TimeToLocMs(startTime, loc) // 毫秒级时间戳
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}

		endAt, err := helper.TimeToLocMs(endTime, loc) // 毫秒级时间戳
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}

		if startAt >= endAt {
			return data, errors.New(helper.QueryTimeRangeErr)
		}

		ex["created_at"] = g.Op{"between": exp.NewRangeVal(startAt, endAt)}
	}
	uids := make([]string, 0)
	if username != "" { // 用户名校验
		uName, _ := url.PathUnescape(username)
		mb, err := MemberFindByUnameAndOpeId(uName, operatorId)
		if err != nil {
			return data, errors.New(helper.UsernameErr)
		}
		ex["username"] = uName
		ex["uid"] = mb.Uid
	} else {
		members, err := MemberFindByOperatorId(operatorId)
		if err != nil {
			return data, errors.New(helper.OperatorIdErr)
		}
		if len(members) > 0 {
			for _, val := range members {
				uids = append(uids, val.Uid)
			}
			ex["uid"] = uids
		}
	}

	t := dialect.From("tbl_balance_transaction")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT(1)).Where(ex).ToSQL()
		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil {
			return data, pushLog(err, "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}

		query, _, _ = t.Select(g.L("sum(after_amount - before_amount)").As("agg")).Where(ex).ToSQL()
		err = meta.MerchantDB.Get(&data.Agg, query)
		if err != nil {
			return data, pushLog(err, "数据库错误")
		}
	}

	offset := pageSize * (page - 1)
	query, _, _ := t.Select(colsTransaction...).Where(ex).
		Offset(uint(offset)).Limit(uint(pageSize)).Order(g.C("created_at").Desc()).ToSQL()
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(err, "数据库错误")
	}
	return data, nil
}

func BusinessRecordTransaction(page, pageSize int, startTime, endTime, businessId, username string, ex g.Ex) (TransactionData, error) {

	data := TransactionData{}

	if startTime != "" && endTime != "" {
		startAt, err := helper.TimeToLocMs(startTime, loc) // 毫秒级时间戳
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}

		endAt, err := helper.TimeToLocMs(endTime, loc) // 毫秒级时间戳
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}

		if startAt >= endAt {
			return data, errors.New(helper.QueryTimeRangeErr)
		}

		ex["created_at"] = g.Op{"between": exp.NewRangeVal(startAt, endAt)}
	}
	uids := make([]string, 0)
	if username != "" { // 用户名校验
		uName, _ := url.PathUnescape(username)
		mb, err := MemberFindByUnameAndProId(uName, businessId)
		if err != nil {
			return data, errors.New(helper.UsernameErr)
		}
		ex["username"] = uName
		ex["uid"] = mb.Uid
	} else {
		members, err := MemberFindByBusinessId(businessId)
		if err != nil {
			return data, errors.New(helper.BusinessIdErr)
		}
		if len(members) > 0 {
			for _, val := range members {
				uids = append(uids, val.Uid)
			}
			ex["uid"] = uids
		}
	}

	t := dialect.From("tbl_balance_transaction")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT(1)).Where(ex).ToSQL()
		err := meta.MerchantDB.Get(&data.T, query)
		if err != nil {
			return data, pushLog(err, "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}

		query, _, _ = t.Select(g.L("sum(after_amount - before_amount)").As("agg")).Where(ex).ToSQL()
		err = meta.MerchantDB.Get(&data.Agg, query)
		if err != nil {
			return data, pushLog(err, "数据库错误")
		}
	}

	offset := pageSize * (page - 1)
	query, _, _ := t.Select(colsTransaction...).Where(ex).
		Offset(uint(offset)).Limit(uint(pageSize)).Order(g.C("created_at").Desc()).ToSQL()
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(err, "数据库错误")
	}
	return data, nil
}
